package cn.stylefeng.guns.modular.business.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.stylefeng.guns.modular.business.comment.YunHeKey;
import cn.stylefeng.guns.modular.business.entity.SubDic;
import cn.stylefeng.guns.modular.business.entity.SubDrawInfo;
import cn.stylefeng.guns.modular.business.entity.SubFileInfo;
import cn.stylefeng.guns.modular.business.enums.SubDrawInfoExceptionEnum;
import cn.stylefeng.guns.modular.business.mapper.SubDrawInfoMapper;
import cn.stylefeng.guns.modular.business.pojo.SubDrawInfoRequest;
import cn.stylefeng.guns.modular.business.pojo.SubFileInfoRequest;
import cn.stylefeng.guns.modular.business.service.SubDrawInfoService;
import cn.stylefeng.guns.modular.business.service.SubFileInfoService;
import cn.stylefeng.guns.modular.business.service.SubUseBrowseService;
import cn.stylefeng.roses.kernel.auth.api.LoginUserApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
import cn.stylefeng.roses.kernel.db.api.factory.PageFactory;
import cn.stylefeng.roses.kernel.db.api.factory.PageResultFactory;
import cn.stylefeng.roses.kernel.db.api.pojo.page.PageResult;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiModelProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 图片数据业务实现层
 *
 * @author zhangyaowen
 * @date 2021/08/18 14:09
 */
@Service
public class SubDrawInfoServiceImpl extends ServiceImpl<SubDrawInfoMapper, SubDrawInfo> implements SubDrawInfoService {

    @Resource
    private LoginUserApi loginUserApi;
    @Resource
    private SubUseBrowseService subUseBrowseService;
    @Resource
    private SubFileInfoService subFileInfoService;

	@Override
    public void add(SubDrawInfoRequest subDrawInfoRequest) {
        SubDrawInfo subDrawInfo = new SubDrawInfo();
        BeanUtil.copyProperties(subDrawInfoRequest, subDrawInfo);
        this.save(subDrawInfo);
    }

    @Override
    public void del(SubDrawInfoRequest subDrawInfoRequest) {
        SubDrawInfo subDrawInfo = this.querySubDrawInfo(subDrawInfoRequest);
        this.removeById(subDrawInfo.getId());
    }

    @Override
    public void edit(SubDrawInfoRequest subDrawInfoRequest) {
        SubDrawInfo subDrawInfo = this.querySubDrawInfo(subDrawInfoRequest);
        BeanUtil.copyProperties(subDrawInfoRequest, subDrawInfo);
        this.updateById(subDrawInfo);
    }

    @Override
    public SubDrawInfo detail(SubDrawInfoRequest subDrawInfoRequest) {
        return this.querySubDrawInfo(subDrawInfoRequest);
    }

    @Override
    public PageResult<SubDrawInfo> findPage(SubDrawInfoRequest subDrawInfoRequest) {
        LambdaQueryWrapper<SubDrawInfo> wrapper = createWrapper(subDrawInfoRequest);
        Page<SubDrawInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        PageResult<SubDrawInfo> subDrawInfoPageResult = PageResultFactory.createPageResult(sysRolePage);

       // subDrawInfoPageResult.getRows()
        return subDrawInfoPageResult;
    }

    @Override
    public List<SubDrawInfo> findList(SubDrawInfoRequest subDrawInfoRequest) {
        LambdaQueryWrapper<SubDrawInfo> wrapper = this.createWrapper(subDrawInfoRequest);
        return this.list(wrapper);
    }

    @Override
    public PageResult<Map<String,Object>> findOneList(SubDrawInfoRequest subDrawInfoRequest) {
        LambdaQueryWrapper<SubDrawInfo> wrapper = this.createWrapper(subDrawInfoRequest);
        Page<SubDrawInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        PageResult<SubDrawInfo> subDrawInfoPageResult = PageResultFactory.createPageResult(sysRolePage);
        PageResult<Map<String,Object>> pageResult = new PageResult<>();
        List<SubDrawInfo> subDrawInfoList = subDrawInfoPageResult.getRows();
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(SubDrawInfo subDrawInfo:subDrawInfoList){
            SubFileInfoRequest subFileInfoRequest = new SubFileInfoRequest();
            subFileInfoRequest.setFileType(1l);
            subFileInfoRequest.setFileOriginName(subDrawInfo.getDrawName());
            //subFileInfoRequest.setFileSecondBelong("图志");
            List <SubFileInfo> subFileInfoList = subFileInfoService.findListByName(subFileInfoRequest);
            for(SubFileInfo subFileInfo : subFileInfoList){
                Map<String, Object> map = new HashMap<String, Object>();
                map = JSONObject.parseObject(JSONObject.toJSONString(subDrawInfo), Map.class);
                map.put("fileId",subFileInfo.getId());
                map.put("fileOriginName",subFileInfo.getFileOriginName());
                mapList.add(map);
            }
        }
        pageResult.setRows(mapList);
        pageResult.setPageSize(subDrawInfoPageResult.getPageSize());
        pageResult.setPageNo(subDrawInfoPageResult.getPageNo());
        pageResult.setTotalPage(subDrawInfoPageResult.getTotalPage());
        pageResult.setTotalRows(subDrawInfoPageResult.getTotalRows());
        return pageResult;
    }

    @Override
    public PageResult<Map<String,Object>> findAllList(SubDrawInfoRequest subDrawInfoRequest) {
        LambdaQueryWrapper<SubDrawInfo> wrapper = new LambdaQueryWrapper<>();
        String drawSecond = subDrawInfoRequest.getDrawSecond();
        wrapper.like(ObjectUtil.isNotEmpty(drawSecond), SubDrawInfo::getDrawSecond, drawSecond);
        Page<SubDrawInfo> sysRolePage = this.page(PageFactory.defaultPage(), wrapper);
        PageResult<SubDrawInfo> subDrawInfoPageResult = PageResultFactory.createPageResult(sysRolePage);
        PageResult<Map<String,Object>> pageResult = new PageResult<>();
        List<SubDrawInfo> subDrawInfoList =  subDrawInfoPageResult.getRows();
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(SubDrawInfo subDrawInfo:subDrawInfoList){
            SubFileInfoRequest subFileInfoRequest = new SubFileInfoRequest();
            subFileInfoRequest.setFileType(1l);
            subFileInfoRequest.setFileOriginName(subDrawInfo.getDrawFilename());
            //subFileInfoRequest.setFileSecondBelong("图志");
            List <SubFileInfo> subFileInfoList =  subFileInfoService.findListByName(subFileInfoRequest);
            for(SubFileInfo subFileInfo : subFileInfoList){
                Map<String, Object> map = new HashMap<String, Object>();
                map = JSONObject.parseObject(JSONObject.toJSONString(subDrawInfo), Map.class);
                byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
                SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

                String jmid = YunHeKey.YHTZ+subDrawInfo.getId();
                String encryptHex = aes.encryptHex(jmid);
                map.put("id",encryptHex);
                map.put("fileId",subFileInfo.getId());
                map.put("fileOriginName",subFileInfo.getFileOriginName());
                mapList.add(map);
            }
        }
        pageResult.setRows(mapList);
        pageResult.setPageSize(subDrawInfoPageResult.getPageSize());
        pageResult.setPageNo(subDrawInfoPageResult.getPageNo());
        pageResult.setTotalPage(subDrawInfoPageResult.getTotalPage());
        pageResult.setTotalRows(subDrawInfoPageResult.getTotalRows());
        return pageResult;
	}

    @Override
    public List<Map<String,Object>> findAllListDraw(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<SubDrawInfo> wrapper = createWrapperByTown(riverList,townList,times,name);
        List<SubDrawInfo>  list = this.list(wrapper);
        List<Map<String,Object>> mapList=new ArrayList<>();
        for(SubDrawInfo subDrawInfo:list) {
            Map<String, Object> map = new HashMap<String, Object>();
            SubFileInfoRequest subFileInfoRequest = new SubFileInfoRequest();
            subFileInfoRequest.setFileType(1l);
            subFileInfoRequest.setFileOriginName(subDrawInfo.getDrawFilename());
            //subFileInfoRequest.setFileSecondBelong("图志");
            List <SubFileInfo> subFileInfoList =  subFileInfoService.findListByName(subFileInfoRequest);
            for(SubFileInfo subFileInfo : subFileInfoList){
                map.put("fileId",subFileInfo.getId());
                map.put("fileOriginName",subFileInfo.getFileOriginName());
            }
            map.put("title", subDrawInfo.getDrawName());
            map.put("historyDating",subDrawInfo.getHistoryDating());
            map.put("theCommon",subDrawInfo.getTheCommon());
            map.put("from",subDrawInfo.getDrawLaiyuanzhishu() );
            map.put("createTime", DateUtil.format(subDrawInfo.getCreateTime(), "yyyy-MM-dd"));
            map.put("type",YunHeKey.YHTZ);
            byte[] key = YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);

            String jmid = YunHeKey.YHTZ+subDrawInfo.getId();
            String encryptHex = aes.encryptHex(jmid);
            map.put("id",encryptHex);
            mapList.add(map);
        }
        return mapList;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/30 10:17
     */
    private LambdaQueryWrapper<SubDrawInfo> createWrapperByTown(List<SubDic> riverList, List<SubDic> townList, String[] times, String name) {
        LambdaQueryWrapper<SubDrawInfo> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.and(i-> i.like(ObjectUtil.isNotNull(name), SubDrawInfo::getDrawName, name).or()
                .like(ObjectUtil.isNotNull(name), SubDrawInfo::getHistoryDating, name).or()
                .like(ObjectUtil.isNotNull(name), SubDrawInfo::getDrawDreamer, name).or()
                .like(ObjectUtil.isNotNull(name), SubDrawInfo::getTheCommon, name).or()
                .like(ObjectUtil.isNotNull(name), SubDrawInfo::getDrawLaiyuanzhishu, name).or());
        if( !riverList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < riverList.size(); i++) {
                    String dicAname = riverList.get(i).getDicAname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicAname), SubDrawInfo::getDrawRelevantRiver, dicAname);
                    if (i != riverList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        if( !townList.isEmpty()) {
            queryWrapper.and(wrapper -> {
                for (int i = 0; i < townList.size(); i++) {
                    String dicZname = townList.get(i).getDicZname();
                    wrapper.like(ObjectUtil.isNotEmpty(dicZname), SubDrawInfo::getDrawRelevantLocation, dicZname);
                    if (i != townList.size() - 1) {
                        wrapper.or();
                    }
                }
            });
        }
        return queryWrapper;
    }
	
    /**
     * 获取信息
     *
     * @author zhangyaowen
     * @date 2021/08/18 14:09
     */
    private SubDrawInfo querySubDrawInfo(SubDrawInfoRequest subDrawInfoRequest) {
        SubDrawInfo subDrawInfo = this.getById(subDrawInfoRequest.getId());
        if (ObjectUtil.isEmpty(subDrawInfo)) {
            throw new ServiceException(SubDrawInfoExceptionEnum.SUBDRAWINFO_NOT_EXISTED);
        }
        return subDrawInfo;
    }

    /**
     * 创建查询wrapper
     *
     * @author zhangyaowen
     * @date 2021/08/18 14:09
     */
    private LambdaQueryWrapper<SubDrawInfo> createWrapper(SubDrawInfoRequest subDrawInfoRequest) {
        LambdaQueryWrapper<SubDrawInfo> queryWrapper = new LambdaQueryWrapper<>();

        Long id = subDrawInfoRequest.getId();
        String drawSecond = subDrawInfoRequest.getDrawSecond();
        String drawThree = subDrawInfoRequest.getDrawThree();
        String drawName = subDrawInfoRequest.getDrawName();
        String historyDating = subDrawInfoRequest.getHistoryDating();
        String theCommon = subDrawInfoRequest.getTheCommon();
        String drawDreamer = subDrawInfoRequest.getDrawDreamer();
        String drawFilename = subDrawInfoRequest.getDrawFilename();
        String drawForm = subDrawInfoRequest.getDrawForm();
        String drawSize = subDrawInfoRequest.getDrawSize();
        String drawTechnique = subDrawInfoRequest.getDrawTechnique();
        String drawCollect = subDrawInfoRequest.getDrawCollect();
        String drawRecording = subDrawInfoRequest.getDrawRecording();
        String drawCase = subDrawInfoRequest.getDrawCase();
        String drawDescribe = subDrawInfoRequest.getDrawDescribe();
        String drawElaborate = subDrawInfoRequest.getDrawElaborate();
        String drawRelevantLocation = subDrawInfoRequest.getDrawRelevantLocation();
        String drawRelevantRiver = subDrawInfoRequest.getDrawRelevantRiver();
        String drawRelevantFigure = subDrawInfoRequest.getDrawRelevantFigure();
        String drawLaiyuanzhishu = subDrawInfoRequest.getDrawLaiyuanzhishu();
        String drawZhishupage = subDrawInfoRequest.getDrawZhishupage();
        String drawPath = subDrawInfoRequest.getDrawPath();

        queryWrapper.eq(ObjectUtil.isNotNull(id), SubDrawInfo::getId, id);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawSecond), SubDrawInfo::getDrawSecond, drawSecond);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawThree), SubDrawInfo::getDrawThree, drawThree);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawName), SubDrawInfo::getDrawName, drawName);
        queryWrapper.like(ObjectUtil.isNotEmpty(historyDating), SubDrawInfo::getHistoryDating, historyDating);
        queryWrapper.like(ObjectUtil.isNotEmpty(theCommon), SubDrawInfo::getTheCommon, theCommon);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawDreamer), SubDrawInfo::getDrawDreamer, drawDreamer);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawFilename), SubDrawInfo::getDrawFilename, drawFilename);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawForm), SubDrawInfo::getDrawForm, drawForm);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawSize), SubDrawInfo::getDrawSize, drawSize);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawTechnique), SubDrawInfo::getDrawTechnique, drawTechnique);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawCollect), SubDrawInfo::getDrawCollect, drawCollect);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawRecording), SubDrawInfo::getDrawRecording, drawRecording);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawCase), SubDrawInfo::getDrawCase, drawCase);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawDescribe), SubDrawInfo::getDrawDescribe, drawDescribe);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawElaborate), SubDrawInfo::getDrawElaborate, drawElaborate);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawRelevantLocation), SubDrawInfo::getDrawRelevantLocation, drawRelevantLocation);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawRelevantRiver), SubDrawInfo::getDrawRelevantRiver, drawRelevantRiver);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawRelevantFigure), SubDrawInfo::getDrawRelevantFigure, drawRelevantFigure);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawLaiyuanzhishu), SubDrawInfo::getDrawLaiyuanzhishu, drawLaiyuanzhishu);
        queryWrapper.eq(ObjectUtil.isNotNull(drawZhishupage), SubDrawInfo::getDrawZhishupage, drawZhishupage);
        queryWrapper.like(ObjectUtil.isNotEmpty(drawPath), SubDrawInfo::getDrawPath, drawPath);

        return queryWrapper;
    }


    @Override
    public List<Map<String, Object>> toSubDrawInfoReview(String  id) {
        byte[] key =YunHeKey.PASSWORD.getBytes(StandardCharsets.UTF_8);
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key);
        String decryptStr = aes.decryptStr(id, CharsetUtil.CHARSET_UTF_8);
        //获取ID字符串YHSJ后面真实的的id
        String name = StrUtil.subAfter(decryptStr,YunHeKey.YHTZ,false);
        HttpServletRequest request = HttpServletUtil.getRequest();
        Long userid ;
        if (ObjectUtil.isNotNull(request)) {
            LoginUser loginUser = loginUserApi.getLoginUser();
            userid = loginUser.getUserId();
        } else {
            throw new ServiceException(SubDrawInfoExceptionEnum.REQUEST_EMPTY);
        }
        LambdaQueryWrapper<SubDrawInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(name), SubDrawInfo::getId, name);
        List<SubDrawInfo> subDrawInfos =  this.list(queryWrapper);
        if(userid != 0l && userid != -1l) {
            subUseBrowseService.saveBrowse(YunHeKey.TUZHI,subDrawInfos.get(0).getDrawName(),userid,request);
        }
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (SubDrawInfo subDrawInfo : subDrawInfos) {

            Map<String, Object> map = new HashMap<String, Object>();
            map = JSONObject.parseObject(JSONObject.toJSONString(subDrawInfo), Map.class);

            // 获取类的属性
            Field[] declaredFields = SubDrawInfo.class.getDeclaredFields();
            List<Map<String, Object>> mplist = new ArrayList<>();
            // 遍历属性，获取属性上ApiModelProperty的值，属性的名，存入Properties
            if (declaredFields.length != 0) {

                int i = 1;
                Map<String, Object> p = new HashMap<String, Object>();
                for (Field field : declaredFields) {

                    Map<String, Object> mp = new HashMap<String, Object>();
                    if (field.getAnnotation(ApiModelProperty.class) != null) {
                        //获取注解属性
                        ApiModelProperty aa = field.getAnnotation(ApiModelProperty.class);
                        // key和value可根据需求存
                        // 这存的key为注解的值，value为类属性名
                        if (!"drawName".equals(field.getName())) {

                            if ("drawDescribe".equals(field.getName()) || "drawElaborate".equals(field.getName()) || "drawName".equals(field.getName()) ) {
                                p.put(field.getName(), map.get(field.getName()));
                            } else {
                                mp.put("key", aa.value());
                                mp.put("value", map.get(field.getName()));

                                if (i != 1) {
                                    mplist.add(mp);
                                }
                            }
                        }
                    }
                    i++;
                }
                p.put("list", mplist);
                if (i != 1) {
                    mapList.add(p);
                }
            }
        }
        return mapList;
    }

}